package com.java.Collection.List.ArrayList.source_analyze.source_code;

import java.util.Arrays;
import java.util.Collection;

public class ArrayList<E> {
    // modCount指集合变化的次数，与迭代器并发修改异常相关
    
    // 存集合的数组
    transient Object[] elementData;
    // 元素实际数量
    private int size;
    private static final int DEFAULT_CAPACITY = 10;
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    private static final Object[] EMPTY_ELEMENTDATA = {};
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    
    
    // ①默认初始化容量为0，构造函数指定容量时则为指定容量，构造函数指定集合时则为集合长度
    public ArrayList() {
        // 默认初始化容量为0
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            // 构造函数指定容量时则为指定容量
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
        }
    }
    
    public ArrayList(Collection<? extends E> c) {
        Object[] a = c.toArray();
        if ((size = a.length) != 0) {
            // 构造函数指定集合时则为集合长度
            if (c.getClass() == java.util.ArrayList.class) {
                elementData = a;
            } else {
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {
            elementData = EMPTY_ELEMENTDATA;
        }
    }
    
    public boolean add(E e) {
        // 与真正扩容步骤②③④⑤相关的入口在此⭐⭐⭐
        ensureCapacityInternal(size + 1);
        
        elementData[size++] = e;
        return true;
    }
    
    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        
        // 与真正扩容步骤②③④⑤相关的入口在此⭐⭐⭐
        ensureCapacityInternal(size + numNew);
        
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }
    
    private void ensureCapacityInternal(int minCapacity) { // 参数为加上新增加元素后的扩容最小容量
        // calculateCapacity：元素为空时扩容后容量为10，元素不为空时扩容后容量为加上新增加元素后的扩容最小容量
        // ensureExplicitCapacity：扩容
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        // ②原容量为0时无法存下新添加的元素，则扩容为10后存
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
    
    private void ensureExplicitCapacity(int minCapacity) {
        // modCount++;
        
        // ③原容量能存下新添加的元素，则无需扩容直接存
        if (minCapacity - elementData.length > 0)
            // 扩容
            grow(minCapacity);
    }
    
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        
        // ④原容量无法存下新添加的元素但根据(原容量*1.5)求得的扩容容量能存下新添加的元素，则扩容为(原容量*1.5)后存
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            // ②原容量为0时无法存下新添加的元素，则扩容为10后存
            // ⑤原容量无法存下新添加的元素且根据(原容量*1.5)求得的扩容容量也无法存下新添加的元素，则扩容为加上新增加元素后的实际容量存
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            // 扩容后容量非法时进入hugeCapacity方法进行大容量扩容
            newCapacity = hugeCapacity(minCapacity);
        
        // 扩容完成
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    
    private static int hugeCapacity(int minCapacity) {
        // 加上新增加元素后的扩容最小容量超出Integer最大值则抛出异常
        if (minCapacity < 0)
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }
    
    public int capacity() {
        return elementData.length;
    }
}
